package com.woniu.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniu.entity.Comment;
import com.woniu.entity.User;
import com.woniu.model.Result;
import com.woniu.service.CommentService;
import com.woniu.service.UserService;
import com.woniu.service.util.UserTokenUtil;
import com.woniu.service.vo.CommentVo;
import com.woniu.service.vo.TestPageVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author D
 * @since 2023-03-27 08:24:57
 */
@RestController
@RequestMapping("/comment")
public class CommentController {
    @Autowired
    private CommentService commentService;

    @Autowired
    private UserService userService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 根据靶场编号获取评论列表
     *
     * @param testCode    靶场编号
     * @param currentPage 当前页码
     * @param pageSize    每页大小
     * @return TestPageVo<CommentVo> 包含评论列表的分页对象
     */
    @GetMapping("getCommentByTestCode")
    public Result<TestPageVo<CommentVo>> getCommentByTestCode(HttpServletRequest request, Long testCode, Long currentPage, Long pageSize) {
        String userCode = UserTokenUtil.getUserAccount(request);
        TestPageVo<CommentVo> commentByTestCode = commentService.getCommentByTestCode(testCode, currentPage, pageSize, userCode);
        return Result.successResult(commentByTestCode);
    }

    /**
     * 添加评论
     *
     * @param comment     评论内容
     * @param testCode    靶场编号
     * @param parentId    父评论编号
     * @return 成功或失败的消息
     */
    @RequestMapping("/addComment")
    public Result<String> addComment(String comment, String testCode, Long parentId, HttpServletRequest request) {
        long testId = Long.parseLong(testCode);
        Long userCode = Long.parseLong(UserTokenUtil.getUserAccount(request));
        QueryWrapper<Comment> queryWrapper = new QueryWrapper();
        queryWrapper.eq("display", 1);
        Comment comment1 = new Comment().setDisplay(0);
        commentService.update(comment1, queryWrapper);

        User user = userService.getById(userCode);
        Comment comments = new Comment();
        comments.setTestCode(testId).setCommentedCode(testId)
                .setCommentCode(userCode).setUsername(user.getUsername())
                .setCommentDetail(comment).setProfilePhoto(user.getProfilePhoto())
                .setLikeNumber(0).setDisplay(0)
                .setCommentCreateTime(new Date()).setParentId(parentId);

        commentService.save(comments);

        TestPageVo<CommentVo> commentByTestCode = (TestPageVo<CommentVo>) redisTemplate.opsForValue().get("-" + userCode + "comment" + testCode);
        updateReds(comments, commentByTestCode);
        redisTemplate.opsForValue().set("-" + userCode + "comment" + testCode, commentByTestCode,1, TimeUnit.DAYS);
        return Result.successResult("ok");
    }

    /**
     * 更新redis中的回复数据
     * @param comments 新建的评论
     * @param commentByTestCode redis中的评论数据
     * @return
     */
    private TestPageVo<CommentVo> updateReds(Comment comments, TestPageVo<CommentVo> commentByTestCode) {
        List<CommentVo> commentVos = commentByTestCode.getPageVo();
        for (CommentVo commentVo : commentVos) {
            if (commentVo.getId().equals(comments.getParentId())) {
                CommentVo commentVo1 = new CommentVo(comments);
                commentVo.getChildren().add(commentVo1);
            }
        }
        return commentByTestCode;
    }

    /**
     * 更新评论状态
     * @param id  评论编号
     * @param num 状态值,是否显示
     * @return 成功或失败的消息
     */
    @RequestMapping("/update")
    public Result<String> update(Long id, Integer num) {
        Comment comment = commentService.getById(id);
        comment.setDisplay(num);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("display", 1);
        Comment comment1 = new Comment().setDisplay(0);
        commentService.update(comment1, queryWrapper);
        commentService.updateById(comment);
        return Result.successResult("ok");
    }

    /**
     * 更新点赞数
     * @param id 评论编号
     * @param likeNumber 点赞数
     * @param request 请求
     * @param testCode 靶场编号
     * @param parentId 父评论编号
     * @return 成功或失败的消息
     */
    @RequestMapping("/updateLikeNumber")
    public Result<String> updateLikeNumber(Long id, Integer likeNumber, HttpServletRequest request, Long testCode, Long parentId) {
        Long userCode = Long.valueOf(UserTokenUtil.getUserAccount(request));
        TestPageVo<CommentVo> commentByTestCode = (TestPageVo<CommentVo>) redisTemplate.opsForValue().get("-" + userCode + "comment" + testCode);
        if (commentByTestCode != null) {
            List<CommentVo> pageVo = commentByTestCode.getPageVo();
            for (CommentVo comment : pageVo) {
                likeNumber = setIsLike(id, comment, likeNumber);
                if (comment.getChildren().size() > 0) {
                    for (CommentVo commentVo : comment.getChildren()) {
                        likeNumber = setIsLike(id, commentVo, likeNumber);
                    }
                }
            }
        }
        Comment comment = new Comment().setId(id).setLikeNumber(likeNumber).setParentId(parentId)
                .setTestCode(testCode);
        redisTemplate.opsForValue().set("-" + userCode + "comment" + testCode, commentByTestCode, 1, TimeUnit.DAYS);
        commentService.updateById(comment);
        return Result.successResult("ok");
    }

    /**
     * 判断是否点赞,并更新点赞次数,根据是否点赞进行+-1操作
     * @param id 评论id
     * @param commentVo 评论对象
     * @param likeNumber 点赞次数
     * @return 更新后的点赞次数
     */
    public Integer setIsLike(Long id, CommentVo commentVo, Integer likeNumber) {
        if (id.equals(commentVo.getId()) && new Integer(1).equals(commentVo.getIsLike())) {
            likeNumber = likeNumber - 1;
            commentVo.setIsLike(0);
            commentVo.setLikeNumber(likeNumber);
        } else if (commentVo.getId().equals(id) && new Integer(0).equals(commentVo.getIsLike())) {
            likeNumber = likeNumber + 1;
            commentVo.setIsLike(1);
            commentVo.setLikeNumber(likeNumber);
        }
        return likeNumber;
    }

}

